<script setup lang="ts">
import { ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { DictEnum } from '@vben/constants';
import { $t } from '@vben/locales';
import { addFullName, getPopupContainer, listToTree } from '@vben/utils';

import { useVbenForm } from '#/adapter/form';
import { menuAdd, menuInfo, menuList, menuUpdate } from '#/api/system/menu';
import { getDictOptions } from '#/utils/dict';

import { menuTypeOptions, yesNoOptions } from './table-data';

const emit = defineEmits<{ reload: [] }>();
// 侧拉内置容器 Form表单的配置项
const [Form, FormApi] = useVbenForm({
  // 不显示提交和重置按钮
  showDefaultActions: false,
  // 垂直布局，label和input在不同行，值为vertical
  // 水平布局，label和input在同一行
  layout: 'horizontal',
  schema: [
    {
      component: 'Input',
      fieldName: 'menuId',
      dependencies: {
        show: () => false,
        triggerFields: [''],
      },
    },
    {
      component: 'ApiTreeSelect',
      componentProps: {
        api: async () => {
          const menuArray = await menuList();
          // support i18n
          menuArray.forEach((item) => {
            item.menuName = $t(item.menuName);
          });
          // const folderArray = menuArray.filter((item) => item.menuType === 'M');
          /**
           * 这里需要过滤掉按钮类型
           * 不允许在按钮下添加数据
           */
          const filteredList = menuArray.filter(
            (item) => item.menuType !== 'F',
          );
          const menuTree = listToTree(filteredList, {
            id: 'menuId',
            pid: 'parentId',
          });
          const fullMenuTree = [
            {
              menuId: 0,
              menuName: $t('menu.root'),
              children: menuTree,
            },
          ];
          addFullName(fullMenuTree, 'menuName', ' / ');
          return fullMenuTree;
        },
        getPopupContainer,
        labelField: 'menuName',
        valueField: 'menuId',
        childrenField: 'children',
        checkStrictly: true,
      },
      defaultValue: 0,
      rules: 'selectRequired',
      fieldName: 'parentId',
      label: $t('menus.parentId'),
    },
    {
      component: 'RadioGroup',
      fieldName: 'menuType',
      label: $t('menus.menu-type'),
      defaultValue: 'M',
      componentProps: {
        buttonStyle: 'solid',
        isButton: true,
        options: menuTypeOptions,
        optionType: 'button',
      },
    },
    {
      component: 'IconPicker',
      componentProps: {
        prefix: 'carbon',
      },
      dependencies: {
        show: (values) => {
          return values.menuType !== 'F';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'icon',
      label: $t('menus.icon'),
    },
    {
      component: 'Input',
      fieldName: 'menuName',
      componentProps: {
        maxlength: 50,
      },
      label: $t('menus.menu-name'),
      rules: 'required',
    },
    {
      component: 'InputNumber',
      fieldName: 'orderNum',
      componentProps: {
        max: 9999,
      },
      defaultValue: 0,
      label: $t('menus.order-num'),
      rules: 'required',
    },
    {
      component: 'Input',
      dependencies: {
        show: (values) => {
          return values.menuType !== 'F';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'path',
      componentProps: {
        maxlength: 200,
      },
      label: $t('menus.path'),
      rules: 'required',
    },
    {
      component: 'Input',
      dependencies: {
        show: (values) => {
          return values.menuType === 'C';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'component',
      componentProps: {
        maxlength: 255,
      },
      label: $t('menus.component'),
      rules: 'required',
    },
    {
      component: 'Input',
      dependencies: {
        show: (values) => {
          return values.menuType !== 'M';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'perms',
      componentProps: {
        maxlength: 100,
      },
      label: $t('menus.perms'),
    },
    {
      component: 'RadioGroup',
      dependencies: {
        show: (values) => {
          return values.menuType !== 'F';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'isFrame',
      label: $t('menus.is-frame'),
      defaultValue: '1',
      componentProps: {
        buttonStyle: 'solid',
        isButton: true,
        options: yesNoOptions,
        optionType: 'button',
      },
    },
    {
      component: 'RadioGroup',
      dependencies: {
        show: (values) => {
          return values.menuType !== 'F';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'visible',
      label: $t('menus.is-visible'),
      defaultValue: '0',
      componentProps: {
        buttonStyle: 'solid',
        isButton: true,
        options: getDictOptions(DictEnum.SYS_SHOW_HIDE),
        optionType: 'button',
      },
    },
    {
      component: 'RadioGroup',
      dependencies: {
        show: (values) => {
          return values.menuType !== 'F';
        },
        triggerFields: ['menuType'],
      },
      fieldName: 'status',
      label: $t('menus.status'),
      defaultValue: '0',
      componentProps: {
        buttonStyle: 'solid',
        isButton: true,
        options: getDictOptions(DictEnum.SYS_NORMAL_DISABLE),
        optionType: 'button',
      },
    },
  ],
});
interface ModalProps {
  id?: number | string;
  update: boolean;
}
// 新增还是修改的标识
const isUpdate = ref<boolean>(false);

const [Drawer, DrawerApi] = useVbenDrawer({
  // 点击侧拉的确定按钮执行逻辑
  async onConfirm() {
    try {
      DrawerApi.drawerLoading(true);
      const { valid } = await FormApi.validate();
      if (!valid) {
        return;
      }
      const data = await FormApi.getValues();
      await (isUpdate.value ? menuUpdate(data) : menuAdd(data));
      emit('reload');
      DrawerApi.close();
      await FormApi.resetForm();
    } catch (error) {
      console.error(error);
    } finally {
      DrawerApi.drawerLoading(false);
    }
  },
  // 调用drawApi.setData方法的时候会触发
  async onOpenChange(isOpen) {
    if (!isOpen) {
      return null;
    }
    const { id, update } = DrawerApi.getData() as ModalProps;
    isUpdate.value = update;
    if (id) {
      await FormApi.setFieldValue('parentId', id);
      if (update) {
        const record = await menuInfo(id);
        await FormApi.setValues(record);
      }
    }
  },
});
</script>
<template>
  <Drawer :title="isUpdate ? $t('common.modify') : $t('common.add')">
    <Form />
  </Drawer>
</template>
<style scoped lang="scss">
:deep(.el-input-number) {
  width: 100%;
}

:deep(button) {
  width: 100%;
}
</style>
